package no.sachmuld.methodcombination.impl.reflection;

import no.sachmuld.methodcombination.api.BehaviourChain;
import no.sachmuld.methodcombination.api.reflection.component.DelegatingMethodCombination;

/**
 *
 */
public interface ExceptionMapper {

    public static class ExceptionMapper1 <B, R, E extends Exception> {

        private DelegatingMethodCombination<B, R> methodCombination;
        private Class<E> e1;

        public ExceptionMapper1(DelegatingMethodCombination<B, R> methodCombination, Class<E> e1) {
            this.methodCombination = methodCombination;
            this.e1 = e1;
        }

        public R execute(Object targetObject, BehaviourChain chain, Object... parameters) throws E {
            try {
                return methodCombination.execute(targetObject, chain, parameters);
            } catch (MethodCombinationInvocationException e) {
                Throwable cause = e.getCause();
                if (cause.getClass().isAssignableFrom(e1)) {
                    throw (E) cause;
                } else {
                    throw e;
                }
            }
        }
    }
}
